#include <stdio.h>
#include <string>
#include <vector>
#include <map>

using namespace std;

#include "bkbase.h"
#include "bstcp.h"

#include "h_base.h"
using namespace h_base;

#include "simbat_plugin.h"

#define TIME_OUT 10000

static bool FirstFlag = true;
static string Addr;
static int Port = 0;
static string Service;
static char Body[1024 * 1024 + 1];

static int HttpPost(const char *Header, const char *Body, int BodyLen, char ErrStr[200 + 1])
{
fprintf(stderr, "HEADER :\n%s\nBODY :\n%s\n", Header, Body);
return 0;
   int Sock = BsCreateClientSocket(Addr.c_str(), Port, TIME_OUT);

   if ( Sock < 0 )
   {
      snprintf(ErrStr, 200, "BsCreateClientSocket(%s, %d) fail, errno = %d", Addr.c_str(), Port, errno);
      return 8;
   }

   int r = BsWriteToSocket(Sock, Header, strlen(Header), TIME_OUT);

   if ( r < 0 )
   {
      snprintf(ErrStr, 200, "BsWriteToSocket fail, r = %d, errno = %d", r, errno);
      close(Sock);
      return 8;
   }

   r = BsWriteToSocket(Sock, Body, BodyLen, TIME_OUT);

   if ( r < 0 )
   {
      snprintf(ErrStr, 200, "BsWriteToSocket fail, r = %d, errno = %d", r, errno);
      close(Sock);
      return 8;
   }

   close(Sock);
   return 0;
}

int SimbatPluginPushOutline(const char *InfoStrArray[], int Qty, char ErrStr[200 + 1])
{
   if ( FirstFlag )
   {
      char Url[80 + 1];
      void *Handle = NULL;
      ErrStr[0] = '\0';
      Handle = SimbatOpenConfig(ErrStr);
      if ( Handle == NULL )
      {
         return 8;
      }
      SimbatConfigGetValue(Handle, NULL, "URL_OUTLINE", Url, 80);
      const char *s = Url;
      int Pos = 0;
      if ( memcmp(s, "http://", 7) == 0 )
      {
         Pos += 7;
      }
      int Begin = Pos;
      for ( ; s[Pos] != '\0' && s[Pos] != ':' && s[Pos] != '/'; Pos++ )
         ;
      Addr = string(s + Begin, Pos - Begin);
      if ( s[Pos] == ':' )
      {
         Pos++;
         Port = BkStrToInt(s + Pos);
         for ( ; s[Pos] != '\0' && s[Pos] != '/'; Pos++ )
            ;
      }
      Service = string(s + Pos);
      if ( Addr == "" || Port <= 0 || Service == "" )
      {
         snprintf(ErrStr, 200, "Invalid url '%s'", Url);
         return 8;
      }
      SimbatCloseConfig(Handle);
      FirstFlag = false;
   }

   char Header[2048 + 1];
   int BodyLen = 0;

   BodyLen += snprintf(Body + BodyLen, 1024 * 1024 - BodyLen, "[");

   for ( int i = 0; i < Qty; i++ )
   {
      const char *InfoStr = InfoStrArray[i];
      vector<HString> StrVec;
      SplitString(InfoStr, '|', StrVec, true);
      if ( StrVec.size() < 19 )
      {
         snprintf(ErrStr, 200, "Syntax error, '%s'", InfoStr);
         return 8;
      }
      const char *System = StrVec.size() > 0 ? StrVec[0].c_str() : "";
      const char *Description = StrVec.size() > 1 ? StrVec[1].c_str() : "";
      const char *BatchDate = StrVec.size() > 2 ? StrVec[2].c_str() : "";
      const char *BatchStartTime = StrVec.size() > 3 ? StrVec[3].c_str() : "";
      const char *BatchEndTime = StrVec.size() > 4 ? StrVec[4].c_str() : "";
      const char *Section = StrVec.size() > 5 ? StrVec[5].c_str() : "";
      const char *BatchStatus = StrVec.size() > 6 ? StrVec[6].c_str() : "";
      const char *TotalJobQty = StrVec.size() > 7 ? StrVec[7].c_str() : "";
      const char *SuccessJobQty = StrVec.size() > 8 ? StrVec[8].c_str() : "";
      const char *RunningJobQty = StrVec.size() > 9 ? StrVec[9].c_str() : "";
      const char *FailedJobQty = StrVec.size() > 10 ? StrVec[10].c_str() : "";
      const char *SkippedJobQty = StrVec.size() > 11 ? StrVec[11].c_str() : "";
      const char *WaitingJobQty = StrVec.size() > 12 ? StrVec[12].c_str() : "";
      const char *SectionTotalJobQty = StrVec.size() > 13 ? StrVec[13].c_str() : "";
      const char *SectionSuccessJobQty = StrVec.size() > 14 ? StrVec[14].c_str() : "";
      const char *SectionRunningJobQty = StrVec.size() > 15 ? StrVec[15].c_str() : "";
      const char *SectionFailedJobQty = StrVec.size() > 16 ? StrVec[16].c_str() : "";
      const char *SectionSkippedJobQty = StrVec.size() > 17 ? StrVec[17].c_str() : "";
      const char *SectionWaitingJobQty = StrVec.size() > 18 ? StrVec[18].c_str() : "";
      int CompleteRate = 0;
      {
         int TotalQty = StrToInt(TotalJobQty);
         int CompleteQty = StrToInt(SuccessJobQty) + StrToInt(SkippedJobQty);
         CompleteRate = TotalQty == 0 ? 0 : CompleteQty * 100 / TotalQty;
      }
      int SectionCompleteRate = 0;
      {
         int TotalQty = StrToInt(SectionTotalJobQty);
         int CompleteQty = StrToInt(SectionSuccessJobQty) + StrToInt(SectionSkippedJobQty);
         SectionCompleteRate = TotalQty == 0 ? 0 : CompleteQty * 100 / TotalQty;
      }
      BodyLen += snprintf(Body + BodyLen, 1024 * 1024 - BodyLen,
         "{\"System\":\"%s\","
         "\"Description\":\"%s\","
         "\"BatchDate\":\"%s\","
         "\"BatchStartTime\":\"%s\","
         "\"BatchEndTime\":\"%s\","
         "\"Section\":\"%s\","
         "\"BatchStatus\":\"%s\","
         "\"TotalJobQty\":\"%s\","
         "\"SuccessJobQty\":\"%s\","
         "\"RunningJobQty\":\"%s\","
         "\"FailedJobQty\":\"%s\","
         "\"SkippedJobQty\":\"%s\","
         "\"WaitingJobQty\":\"%s\","
         "\"SectionTotalJobQty\":\"%s\","
         "\"SectionSuccessJobQty\":\"%s\","
         "\"SectionRunningJobQty\":\"%s\","
         "\"SectionFailedJobQty\":\"%s\","
         "\"SectionSkippedJobQty\":\"%s\","
         "\"SectionWaitingJobQty\":\"%s\","
         "\"CompleteRate\":\"%d\","
         "\"SectionCompleteRate\":\"%d\"}",
         System, Description, BatchDate, BatchStartTime, BatchEndTime, Section, BatchStatus,
         TotalJobQty, SuccessJobQty, RunningJobQty, FailedJobQty, SkippedJobQty, WaitingJobQty,
         SectionTotalJobQty, SectionSuccessJobQty, SectionRunningJobQty, SectionFailedJobQty, SectionSkippedJobQty, SectionWaitingJobQty,
         CompleteRate, SectionCompleteRate);
      if ( i != Qty - 1 )
      {
         BodyLen += snprintf(Body + BodyLen, 1024 * 1024 - BodyLen, ",");
      }
   }

   BodyLen += snprintf(Body + BodyLen, 1024 * 1024 - BodyLen, "]");
   snprintf(Header, 2048,
      "POST %s HTTP/1.1\r\n"
      "Host: %s:%d\r\n"
      "Content-Type: application/json\r\n"
      "Content-Length: %d\r\n"
      "Connection: close\r\n"
      "\r\n",
      Service.c_str(), Addr.c_str(), Port, BodyLen);
   return HttpPost(Header, Body, BodyLen, ErrStr);
}
